package com.bby.disk.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.bby.common.exception.BBYException;
import com.bby.common.model.Permission;
import com.bby.common.utils.BBYUtils;
import com.bby.common.utils.StatusCode;
import com.bby.disk.bean.req.OfflineTaskReq;
import com.bby.disk.manager.auth.AuthorityManager;
import com.bby.disk.bean.UploadStatus;
import com.bby.disk.bean.req.SimpleUploadData;
import com.bby.disk.bean.req.UploadTaskInfo;
import com.bby.disk.manager.upload.OfflineTask;
import com.bby.disk.manager.upload.OfflineThreadManager;
import com.bby.disk.util.BBYFileSystem;
import com.bby.disk.service.IUploadService;
import com.bby.disk.manager.upload.UploadManager;
import com.bby.disk.manager.upload.UploadTask;
import com.bby.disk.manager.virtual.VirtualDirectory;
import com.bby.disk.manager.virtual.VirtualFile;
import com.bby.disk.manager.virtual.VirtualManager;
import com.bby.disk.manager.virtual.VirtualPath;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@Service
public class UploadService implements IUploadService {

    @Value(value = "${settings.rootPath}")
    String ROOT_DIR;

    UploadManager uploadManager;

    Logger logger = LoggerFactory.getLogger(this.getClass());

    public UploadService(UploadManager uploadManager) {
        this.uploadManager = uploadManager;
    }

    @Override
    public void preUpload(String userId, UploadTaskInfo uploadTaskInfo) throws BBYException {
        VirtualFile file = uploadTaskInfo.getFileInfo();
        if (uploadTaskInfo.isUsePath()) {
            file.setParent(
                    VirtualManager.findFileByPath(new VirtualPath(uploadTaskInfo.getTarget())).getId());
        } else {
            file.setParent(uploadTaskInfo.getTarget());
        }
        // 权限判断
        VirtualDirectory parentDir = AuthorityManager.create(userId,file.getParent());

        VirtualManager.storageUseCheck(parentDir.getOwner(),file.getSize());
        Permission permission = VirtualManager.getDefaultPermission(parentDir.getOwner(), parentDir);
        // 文件信息设置
        Date date = new Date();
        file.setId(null).setMaker(ObjectUtil.isEmpty(userId) ? "ann" : userId)
                .setOwner(parentDir.getOwner())
                .setCreateTime(date)
                .setFile(true).setPermission(permission);
        if (ObjectUtil.isEmpty(file.getLastModified())){
            file.setLastModified(file.getCreateTime());
        }

        // 秒传
        if (BBYFileSystem.get(file.getMd5()).isFile()){
            VirtualManager.create(file);
            throw new BBYException(StatusCode.OK_FAST_UPLOAD,"秒传");
        }else {
            uploadManager.addReceiveTask(userId, uploadTaskInfo);
        }
    }

    @Override
    public void delTask(String guid) {
        uploadManager.delete(guid);
    }

    @Override
    public UploadStatus getUploadStatus(String guid) throws BBYException {
        return uploadManager.getUploadState(guid);
    }

    @Override
    public void simpleUploadFile(String userId, String guid, SimpleUploadData uploadData) throws BBYException {
        // 一个task同时只允许一个线程操作
        synchronized (uploadManager.getUploadTask(guid)) {
            UploadTask uploadTask = uploadManager.receiveSimple(guid, uploadData);
            if (uploadTask.isFileOk()) {
                VirtualFile virtualFile = uploadTask.getFileInfo();
                BBYFileSystem.add(uploadTask.getTempFile(),virtualFile.getMd5());
                VirtualManager.create(virtualFile);
                uploadManager.delete(guid);
//            MFileLog.addLog(uploadTask.getUserId(), MFileLog.ACTION_FILE_UPLOAD,uploadTask.getTarget()+"/"+uploadTask.name,"上传成功");//写日志
            }
        }
    }


    @Override
    public OfflineTask addOfflineTask(String userId, OfflineTaskReq req) throws BBYException {
        BBYUtils.checkEmpty(req.getUrl(),req.getTarget());
        VirtualDirectory directory = AuthorityManager.create(userId,req.getTarget());
        VirtualFile file = new VirtualFile();
        file.setParent(directory.getId()).setFile(true)
                .setOwner(directory.getOwner()).setMaker(userId);
        Permission permission = VirtualManager.getDefaultPermission(userId, directory);
        file.setPermission(permission);
        OfflineTask task = new OfflineTask();
        task.setId(new ObjectId().toHexString()).setStatus("ready")
                .setFile(file).setUserId(userId).setUrl(req.getUrl());
        OfflineThreadManager.addThreadTask(task);
        return task;
    }

    @Override
    public List<OfflineTask> getOfflineTaskList(String userId) {
        return OfflineThreadManager.listOfflineTask(userId);
    }

    @Override
    public void retryThreadTask(String userId, String taskId) throws BBYException {
        OfflineThreadManager.retryThreadTask(userId, taskId);
    }
    @Override
    public void removeOfflineTask(String userId, String taskId) throws BBYException {
        OfflineThreadManager.removeThreadTask(userId, taskId);
    }
    @Override
    public long getOfflineTaskFinished(String userId, String taskId) throws BBYException {
        BBYUtils.checkEmpty(taskId);
        return OfflineThreadManager.getFinishedSize(userId, taskId);
    }

    @Override
    public OfflineTask getOfflineTask(String userId, String taskId) throws BBYException {
        return OfflineThreadManager.getOfflineTask(userId, taskId);
    }

    @Override
    public void setAvatar(String userId, MultipartFile avatar) throws BBYException {
        try {
            File file = BBYFileSystem.get(userId);
            avatar.transferTo(file);
            BufferedImage pic1 = ImageIO.read(file);
            int width = pic1.getWidth();
            int height = pic1.getHeight();
            width = Math.min(width,height);
            height = width;
            //参数依次为，截取起点的x坐标，y坐标，截取宽度，截取高度
            BufferedImage pic2 = pic1.getSubimage(0, 0, width, height);
            ImageIO.write(pic2, "png", file);

        } catch (IOException e) {
            e.printStackTrace();
            throw new BBYException(StatusCode.FILE_ERROR,"文件有误！");
        }
    }
//    @Override
//    public ServiceResult uploadPartTrunk(String userId, ChunkedUploadData uploadData) throws Exception {
//        UploadTask uploadTask = uploadManager.receiveTrunked(uploadData);
//        ServiceResult result = new ServiceResult();
//        if (uploadTask.isFinished()){
//            result.setCode(HttpStatus.HTTP_OK);
//            result.setMsg("上传完成");
//        }
//        return result;
//    }
//
//    @Override
//    public ServiceResult uploadPartFast(String userId, ChunkedUploadData uploadData) {
//        return null;
//    }
}
